package com.googlecode.jvmpart;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import com.googlecode.jvmpart.proc.JvmProcess;
import com.googlecode.jvmpart.utils.ProcessId;

/**
 * The context of the monitor thread of a JVM process
 * @author chunzhan.he
 *
 */
public class ProcessExecution extends Thread{
	public static final String PID = ProcessId.getPid();
	public static final long PID_TIMESTAMP = System.currentTimeMillis();
	private Map <String, Object> params;
	private int exitCode;
	private String classpath;
	private CountDownLatch countDownLatch;
	private ProcessListener processListener;
	private String jvmProcessClass;
	private List<String> vmArguments = new ArrayList<String>();
	
	/**
	 * Get the parameters that are passed to the JVM process
	 * @return the parameters
	 */
	public Map<String, Object> getParams() {
		return params;
	}
	/**
	 * Set the parameters that will pass to the JVM process
	 * @param params
	 */
	public void setParams(Map<String, Object> params) {
		this.params = params;
	}
	/**
	 * The code of the JVM process exit 
	 * @return {@link JvmProcess#EXIT_CODE_NORMAL} {@link JvmProcess#EXIT_CODE_FAILED}
	 */
	public int getExitCode() {
		return exitCode;
	}
	/**
	 * Get the canonical class name of the JVM process, 
	 * which implements the interface {@link JvmProcess}
	 * @return Canonical name of the class
	 */
	public String getJvmProcessClass() {
		return jvmProcessClass;
	}
	/**
	 * Set the canonical class name of the JVM process, 
	 * which implements the interface {@link JvmProcess}
	 * @param jvmProcessClass Canonical name of the class
	 */
	public void setJvmProcessClass(String jvmProcessClass) {
		this.jvmProcessClass = jvmProcessClass;
	}
	/**
	 * Set the class path for startup the process
	 * @param classpath
	 */
	public void setClasspath(String classpath) {
		this.classpath = classpath;
	}
	public String getClasspath() {
		return classpath;
	}
	public void addVmArgument(String argument) {
		vmArguments.add(argument);
	}
	public List<String> getVmArguments() {
		return vmArguments;
	}
	public CountDownLatch getCountDownLatch() {
		return countDownLatch;
	}
	public void setCountDownLatch(CountDownLatch countDownLatch) {
		this.countDownLatch = countDownLatch;
	}
	/**
	 * Set the java process listener
	 * @param listener the implement of the interface {@link ProcessListener}
	 */
	public void setProcessListener(ProcessListener listener) {
		this.processListener = listener;
	}
	@Override
	public void run() {
		try {
			processListener.beforeProcess(this);
			exitCode = new RealStartProcess().execute(this);
			processListener.afterProcess(this);
		} catch (Exception e) {
			e.printStackTrace();
			exitCode = JvmProcess.EXIT_CODE_FAILED;
		} finally {
			countDownLatch.countDown();
		}
	}
	@Override
	public String toString() {
		return "class:"+jvmProcessClass+";"+"exitCode:"+exitCode+";"+"process:"+getName()+";"+params.toString();
	}
}
